package com.yimu.ymblog.web.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yimu.ymblog.common.constant.RedisConstants;
import com.yimu.ymblog.common.domain.dos.CommentDO;
import com.yimu.ymblog.common.domain.dos.UserInfoDO;
import com.yimu.ymblog.common.domain.mapper.CommentMapper;
import com.yimu.ymblog.common.domain.mapper.UserInfoMapper;
import com.yimu.ymblog.common.domain.web.vo.other.RedisUserInfoRspVO;
import com.yimu.ymblog.common.domain.web.vo.other.UpdateUserInfoReqVO;
import com.yimu.ymblog.common.domain.web.vo.other.WebSiteInfoRspVO;
import com.yimu.ymblog.common.service.RedisService;
import com.yimu.ymblog.common.utils.IpUtil;
import com.yimu.ymblog.common.utils.MyHttpUtil;
import com.yimu.ymblog.common.utils.Response;
import com.yimu.ymblog.web.service.OtherService;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.Optional;

@Service
@Slf4j
public class OtherServiceImpl implements OtherService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private CommentMapper commentMapper;

    /**
     * 获取各大平台热搜
     *
     * @param type
     * @return
     */
    @Override
    public Response hot(String type) {
        String url = "https://www.coderutil.com/api/resou/v1/" + type;
        JSONObject jsonObject = MyHttpUtil.sendCuApiHttpUrl(url);
        return Response.success(jsonObject);
    }

    /**
     * 获取网站相关信息
     *
     * @return
     */
    @Override
    public Response getWebSiteInfo() {
        //获取访问量
        Object count = redisService.getCacheObject(RedisConstants.BLOG_VIEWS_COUNT);
        //获取访客量
        Object visitorAccess = redisService.getCacheObject(RedisConstants.UNIQUE_VISITOR_COUNT);

        WebSiteInfoRspVO webSiteInfoRspVO = WebSiteInfoRspVO.builder()
                .siteAccess(Optional.ofNullable(count).orElse(0))
                .visitorAccess(Optional.ofNullable(visitorAccess).orElse(0)).build();
        return Response.success(webSiteInfoRspVO);
    }

    /**
     * 添加访问量和访客量
     *
     * @return
     */
    @Override
    public Response report() {
        // 获取ip
        String ipAddress = IpUtil.getIp();
        // 通过浏览器解析工具类UserAgent获取访问设备信息
        UserAgent userAgent = IpUtil.getUserAgent(IpUtil.getRequest());
        Browser browser = userAgent.getBrowser();
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
        // 生成唯一用户标识
        String uuid = ipAddress + browser.getName() + operatingSystem.getName();
        String md5 = DigestUtils.md5DigestAsHex(uuid.getBytes());

        if (!redisService.hasHashKey(RedisConstants.UNIQUE_VISITOR, md5)) {
            // 如果该md5不存在，则说明是新访客
            RedisUserInfoRspVO redisUserInfoRspVO = RedisUserInfoRspVO.builder()
                    .currentTime(LocalDateTime.now())
                    .ipAddress(ipAddress)
                    .browser(browser.toString())
                    .operatingSystem(operatingSystem.getName())
                    .build();
            // 存访客信息
            redisService.setCacheHashValue(RedisConstants.UNIQUE_VISITOR, md5, redisUserInfoRspVO);
            // 访客量+1
            redisService.incr(RedisConstants.UNIQUE_VISITOR_COUNT, 1);
        }
        // 访问量+1
        redisService.incr(RedisConstants.BLOG_VIEWS_COUNT, 1);

        return Response.success(IpUtil.getIp2region(ipAddress));
    }

    /**
     * 更改用户资料信息
     *
     * @return
     */
    @Override
    public Response updateUserInfo(UpdateUserInfoReqVO updateUserInfoReqVO) {
        UserInfoDO userInfoDO = UserInfoDO.builder()
                .nickname(updateUserInfoReqVO.getNickname())
                .avatar(updateUserInfoReqVO.getAvatar())
                .build();
        LambdaUpdateWrapper<UserInfoDO> wrapper = new LambdaUpdateWrapper<UserInfoDO>().eq(UserInfoDO::getEmail, updateUserInfoReqVO.getUsername());
        userInfoMapper.update(userInfoDO, wrapper);
        // 如果该用户有评论过文章，还需更改评论表中的对应评论的用户头像 和用户昵称
        // 找出该用户的所有评论 根据email
        LambdaQueryWrapper<CommentDO> wrapper1 = new LambdaQueryWrapper<CommentDO>().eq(CommentDO::getMail, updateUserInfoReqVO.getUsername());
        Long l = commentMapper.selectCount(wrapper1);
        if (l > 0) {
            LambdaUpdateWrapper<CommentDO> wrapper2 = new LambdaUpdateWrapper<CommentDO>()
                    .eq(CommentDO::getMail, updateUserInfoReqVO.getUsername());
            commentMapper.update(CommentDO.builder()
                            .avatar(updateUserInfoReqVO.getAvatar())
                            .nickname(updateUserInfoReqVO.getNickname())
                            .build(),
                    wrapper2);
        }
        return Response.success();
    }

}
